package cn.sunlelin.educationserver.service.Impl;

import cn.sunlelin.educationserver.constant.HttpStatusEnum;
import cn.sunlelin.educationserver.constant.RedisConstant;
import cn.sunlelin.educationserver.entity.User;
import cn.sunlelin.educationserver.mapper.UserMapper;
import cn.sunlelin.educationserver.param.LoginParam;
import cn.sunlelin.educationserver.service.UserService;
import cn.sunlelin.educationserver.util.JWTUtil;
import cn.sunlelin.educationserver.util.StringUtil;
import cn.sunlelin.educationserver.vo.R;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.*;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JavaMailSenderImpl mailSender;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    // application.properties配置的值
    @Value("${spring.mail.username}")
    private String from;
    @Override
    public Boolean createUser(User user) {
        if(this.selectUserByName(user.getUserName())!=null)
            return false;
        String password=user.getPassword();
        user.setEmail(null);
        // 获取加密盐
        String salt = StringUtil.randomEncryptedSalt();
        user.setSalt(salt);
        user.setPassword(DigestUtils.md5Hex(password + salt));
        user.setCreateTime(new Date());
        userMapper.createUser(user);
        return true;
    }

    @Override
    public Boolean updateUser(User user) {
        User t=selectUserAllById(user.getUserId());
        if(t==null)
            return false;
        //判断用户名是否被使用
        if((t.getUserName()==null||!t.getUserName().equals(user.getUserName()))&&this.selectUserByName(user.getUserName())!=null)
            return false;
        user.setUpdateTime(new Date());
        userMapper.updateUser(user);
        return true;
    }

    @Override
    public Boolean updatePassword(User user) {
        User u=userMapper.selectUserAllById(user.getUserId());
        if(u==null)
            return false;
        user.setPassword(DigestUtils.md5Hex(user.getPassword()+u.getSalt()));
        user.setUpdateTime(new Date());
        userMapper.updatePassword(user);
        return true;
    }

    @Override
    public User loginByUserName(User user) {
        User u= userMapper.selectUserByName(user.getUserName());
        user.setPassword(DigestUtils.md5Hex(user.getPassword()+u.getSalt()));
        return userMapper.findUserNameAndPassword(user);
    }
    @Override
    public R login(LoginParam loginParam) {
        if (loginParam == null) return R.error(HttpStatusEnum.PARAM_ILLEGAL);

        // 获取参数
        String email = loginParam.getEmail();
        String password = loginParam.getPassword();

        if (StringUtils.isAnyBlank(email, password)) {
            // 非空
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);
        }else if (!StringUtil.checkEmail(email)) {
            // 邮箱格式校验
            return R.error(HttpStatusEnum.EMAIL_ERROR);
        }else if (!StringUtil.checkPassword(password)) {
            // 密码格式
            return R.error(HttpStatusEnum.PASSWORD_ERROR);
        }

        // 查询结果
        User user = userMapper.selectUserByEmail(email);
        if (user == null) {
            // 用户不存在
            return R.error(HttpStatusEnum.USER_NOT_EXIST);
        }

        // 获取加密盐
        String salt = user.getSalt();

        if(user.getPassword().equals(DigestUtils.md5Hex(password + salt))){
            R r=new R();
            r.setCode(200);
            r.setSuccess(true);
            r.setMessage("登陆成功");
            Map<String,Object> m=new HashMap<>();
            Map<String,String> payload=new HashMap<>();
            payload.put("userId",user.getUserId().toString());
            payload.put("userName",user.getUserName());
            String token= JWTUtil.createToken(payload);

            m.put("token", token);
            m.put("userId", user.getUserId());
            m.put("userName", user.getUserName());
            m.put("avatar",user.getAvatar());
            r.setData(m);
            return r;
        }
        return R.error(HttpStatusEnum.PASSWORD_ERROR);
    }

    @Override
    public R register(LoginParam loginParam) {
        if (loginParam == null) return R.error(HttpStatusEnum.PARAM_ILLEGAL);

        // 获取参数
        String email = loginParam.getEmail();
        String userName = loginParam.getUserName();
        String password = loginParam.getPassword();
        String passwordConfirm = loginParam.getPasswordConfirm();
        String code = loginParam.getCode();

        if (StringUtils.isAnyBlank(email, password, passwordConfirm, code)) {
            // 非空
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);
        }else if (!StringUtil.checkEmail(email)) {
            // 邮箱格式校验
            return R.error(HttpStatusEnum.EMAIL_ERROR);
        }else if(userMapper.selectUserByName(userName)!=null){
            //查询用户名是否已被使用
            return R.error(HttpStatusEnum.USER_NAME_DOUBLE);
        }
        else if (!password.equals(passwordConfirm)) {
            // 密码一致校验
            return R.error(HttpStatusEnum.PASSWORD_INCONSISTENT);
        }else if (!StringUtil.checkPassword(password) || code.length() != 6) {
            // 密码格式和验证码长度校验
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);
        }

        // 查询用户，是否存在
        if (userMapper.selectUserByEmail(email) != null) {
            return R.error(HttpStatusEnum.EMAIL_ALREADY_EXIST);
        }

        // 获取正确的验证码
        String rightCode = redisTemplate.opsForValue().get(RedisConstant.EMAIL + email);
        if (!code.equals(rightCode)) {
            // 验证码比对
            return R.error(HttpStatusEnum.CODE_ERROR);
        }

        // 删除验证码
        redisTemplate.delete(RedisConstant.EMAIL + email);

        // 注册用户
        User user = new User();
        // 获取加密盐
        String salt = StringUtil.randomEncryptedSalt();
        // 邮箱
        user.setEmail(email);
        user.setUserName(userName);
        // 密码加密（原明文密码 + 随机加密盐） md5加密
        user.setPassword(DigestUtils.md5Hex(password + salt));
        // 加密盐
        user.setSalt(salt);
        userMapper.createUser(user);
        // 插入数据
        return R.ok();
    }

    @Override
    public R updateEmail(LoginParam loginParam){
        Integer userId=loginParam.getUserId();
        String email=loginParam.getEmail();
        String code=loginParam.getCode();
        if(StringUtils.isAnyBlank(email,code)){
            // 非空
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);
        }else if (!StringUtil.checkEmail(email)) {
            // 邮箱格式校验
            return R.error(HttpStatusEnum.EMAIL_ERROR);
        }
        User user=userMapper.selectUserAllById(userId);
        if (user == null) {
            // 用户不存在
            return R.error(HttpStatusEnum.USER_NOT_EXIST);
        }
        User tUser=userMapper.selectUserByEmail(loginParam.getEmail());
        if(tUser!=null&&!tUser.getUserId().equals(loginParam.getUserId()))
            return R.error(HttpStatusEnum.EMAIL_DOUBLE_ERROR);
        String rightCode = redisTemplate.opsForValue().get(RedisConstant.EMAIL + email);
        if (!code.equals(rightCode)) {
            // 验证码比对
            return R.error(HttpStatusEnum.CODE_ERROR);
        }
        // 删除验证码
        redisTemplate.delete(RedisConstant.EMAIL + email);
        user.setEmail(email);
        user.setUpdateTime(new Date());
        userMapper.updateEmail(user);
        return R.ok();
    }
    @Override
    public R findPassword(LoginParam loginParam) {
        if (loginParam == null) return R.error(HttpStatusEnum.PARAM_ILLEGAL);

        // 获取参数
        String email = loginParam.getEmail();
        String password = loginParam.getPassword();
        String code = loginParam.getCode();

        if (StringUtils.isAnyBlank(email, password,code)) {
            // 非空
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);
        }else if (!StringUtil.checkEmail(email)) {
            // 邮箱格式校验
            return R.error(HttpStatusEnum.EMAIL_ERROR);
        }else if (!StringUtil.checkPassword(password) || code.length() != 6) {
            // 密码格式
            return R.error(HttpStatusEnum.PASSWORD_ERROR);
        }

        // 构件条件对象 select salt from user where email = #{email} limit 1

        // 查询结果
        User user = userMapper.selectUserByEmail(email);
        if (user == null) {
            // 用户不存在
            return R.error(HttpStatusEnum.USER_NOT_EXIST);
        }

        String rightCode = redisTemplate.opsForValue().get(RedisConstant.EMAIL + email);
        if (!code.equals(rightCode)) {
            // 验证码比对
            return R.error(HttpStatusEnum.CODE_ERROR);
        }
        // 删除验证码
        redisTemplate.delete(RedisConstant.EMAIL + email);
        user.setPassword(DigestUtils.md5Hex(password+user.getSalt()));
        userMapper.updatePassword(user);
        return R.ok();
    }

    @Override
    public List<User> findAll(){
        return userMapper.findAll();
    }

    @Override
    public User selectUserAllById(Integer userId) {
        return userMapper.selectUserAllById(userId);
    }

    @Override
    public Boolean deleteUser(Integer userId) {
        if(userMapper.selectUserAllById(userId)==null)
            return false;
        User user=new User();
        user.setUserId(userId);
        user.setUpdateTime(new Date());
        userMapper.deleteUser(user);
        return true;
    }

    @Override
    public User selectUserByName(String userName) {
        return userMapper.selectUserByName(userName);
    }
}
